"""
操作系统模块回归测试
验证操作系统模块的完整功能和集成测试
"""

import sys
import os
import time
import logging
from datetime import datetime, date

# 添加项目根目录到Python路径
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('tests/os_regression_test.log'),
        logging.StreamHandler()
    ]
)

logger = logging.getLogger(__name__)

class OsRegressionTest:
    """操作系统模块回归测试类"""
    
    def __init__(self):
        self.test_results = []
        self.test_data = {}
        
        # 导入服务类
        from src.app.modules.os.service import OsService
        from src.app.modules.os.cache import OsCache
        from src.app.modules.os.utils import OsUtils
        from src.app.modules.asset.service import AssetService
        
        self.os_service = OsService()
        self.os_cache = OsCache()
        self.os_utils = OsUtils()
        self.asset_service = AssetService()
    
    def run_test(self, test_name, test_func):
        """运行单个测试"""
        logger.info(f"开始测试: {test_name}")
        start_time = time.time()
        
        try:
            result = test_func()
            duration = time.time() - start_time
            
            test_result = {
                'name': test_name,
                'status': 'PASS' if result else 'FAIL',
                'duration': duration,
                'message': '测试通过' if result else '测试失败'
            }
            
            logger.info(f"测试 {test_name}: {test_result['status']} ({duration:.2f}s)")
            
        except Exception as e:
            duration = time.time() - start_time
            test_result = {
                'name': test_name,
                'status': 'ERROR',
                'duration': duration,
                'message': str(e)
            }
            
            logger.error(f"测试 {test_name}: ERROR - {str(e)}")
        
        self.test_results.append(test_result)
        return test_result['status'] == 'PASS'
    
    def setup_test_data(self):
        """设置测试数据"""
        logger.info("设置测试数据...")
        
        try:
            # 获取第一个设备资产用于测试
            asset_list = self.asset_service.get_all_assets()
            if not asset_list:
                raise Exception("没有找到设备资产，无法进行测试")
            
            self.test_data['asset'] = asset_list[0]
            logger.info(f"使用测试设备资产: {self.test_data['asset']['asset_name']}")
            
            return True
            
        except Exception as e:
            logger.error(f"设置测试数据失败: {str(e)}")
            return False
    
    def test_os_utils_validation(self):
        """测试操作系统工具类验证功能"""
        logger.info("测试操作系统工具类验证功能")
        
        # 测试有效数据
        valid_data = {
            'asset_id': self.test_data['asset']['asset_id'],
            'os_name': 'CentOS',
            'version': '7.6',
            'install_dir': '/opt/centos',
            'install_date': '2023-01-01'
        }
        
        is_valid, error_msg = self.os_utils.validate_os_data(valid_data)
        if not is_valid:
            logger.error(f"有效数据验证失败: {error_msg}")
            return False
        
        # 测试无效数据
        invalid_data = {
            'os_name': 'CentOS',
            'version': '7.6'
            # 缺少asset_id
        }
        
        is_valid, error_msg = self.os_utils.validate_os_data(invalid_data)
        if is_valid:
            logger.error("无效数据应该验证失败")
            return False
        
        # 测试操作系统类型判断
        os_type = self.os_utils.get_os_type('CentOS 7.6')
        if os_type != self.os_utils.OS_TYPE_LINUX:
            logger.error(f"操作系统类型判断错误: 期望 {self.os_utils.OS_TYPE_LINUX}, 实际 {os_type}")
            return False
        
        # 测试兼容性检查
        is_compatible, message = self.os_utils.is_os_compatible_with_asset(
            'CentOS 7.6', self.test_data['asset']['asset_type']
        )
        
        logger.info(f"兼容性检查结果: {is_compatible}, {message}")
        
        return True
    
    def test_os_cache_operations(self):
        """测试操作系统缓存操作"""
        logger.info("测试操作系统缓存操作")
        
        test_os_id = 'test_os_cache_id'
        test_os_data = {
            'os_id': test_os_id,
            'os_name': 'Test OS',
            'version': '1.0',
            'asset_name': 'Test Asset'
        }
        
        # 测试设置缓存
        self.os_cache.set_os(test_os_id, test_os_data)
        
        # 测试获取缓存
        cached_data = self.os_cache.get_os(test_os_id)
        if not cached_data or cached_data['os_name'] != 'Test OS':
            logger.error("缓存设置或获取失败")
            return False
        
        # 测试删除缓存
        self.os_cache.delete_os(test_os_id)
        cached_data = self.os_cache.get_os(test_os_id)
        if cached_data is not None:
            logger.error("缓存删除失败")
            return False
        
        # 测试统计信息缓存
        test_stats = {'total_count': 10, 'os_distribution': []}
        self.os_cache.set_statistics(test_stats)
        
        cached_stats = self.os_cache.get_statistics()
        if not cached_stats or cached_stats['total_count'] != 10:
            logger.error("统计信息缓存操作失败")
            return False
        
        # 清理测试缓存
        self.os_cache.clear_cache()
        
        return True
    
    def test_os_crud_operations(self):
        """测试操作系统CRUD操作"""
        logger.info("测试操作系统CRUD操作")
        
        # 准备测试数据
        os_data = {
            'asset_id': self.test_data['asset']['asset_id'],
            'os_name': 'Test Regression OS',
            'version': '1.0',
            'install_dir': '/opt/test_regression',
            'install_date': '2023-01-01'
        }
        
        # 测试创建操作系统
        create_result = self.os_service.create_os(os_data)
        if not create_result['success']:
            logger.error(f"创建操作系统失败: {create_result['message']}")
            return False
        
        os_id = create_result['data']['os_id']
        logger.info(f"创建操作系统成功: {os_id}")
        
        # 测试获取操作系统
        os_details = self.os_service.get_os_by_id(os_id)
        if not os_details:
            logger.error("获取操作系统失败")
            return False
        
        if os_details['os_name'] != 'Test Regression OS':
            logger.error("获取的操作系统数据不正确")
            return False
        
        # 测试更新操作系统
        update_data = {
            'os_name': 'Updated Test OS',
            'version': '2.0',
            'install_dir': '/opt/updated_test'
        }
        
        update_result = self.os_service.update_os(os_id, update_data)
        if not update_result['success']:
            logger.error(f"更新操作系统失败: {update_result['message']}")
            return False
        
        # 验证更新结果
        updated_os = self.os_service.get_os_by_id(os_id)
        if not updated_os or updated_os['os_name'] != 'Updated Test OS':
            logger.error("操作系统更新验证失败")
            return False
        
        # 测试获取操作系统列表
        os_list = self.os_service.get_os_list()
        if not isinstance(os_list, list):
            logger.error("获取操作系统列表失败")
            return False
        
        # 验证新创建的操作系统在列表中
        found = False
        for os_item in os_list:
            if os_item['os_id'] == os_id:
                found = True
                break
        
        if not found:
            logger.error("新创建的操作系统不在列表中")
            return False
        
        # 测试删除操作系统
        delete_result = self.os_service.delete_os(os_id)
        if not delete_result['success']:
            logger.error(f"删除操作系统失败: {delete_result['message']}")
            return False
        
        # 验证删除结果
        deleted_os = self.os_service.get_os_by_id(os_id)
        if deleted_os is not None:
            logger.error("操作系统删除验证失败")
            return False
        
        logger.info("CRUD操作测试完成")
        return True
    
    def test_os_business_constraints(self):
        """测试操作系统业务约束"""
        logger.info("测试操作系统业务约束")
        
        # 准备测试数据
        os_data = {
            'asset_id': self.test_data['asset']['asset_id'],
            'os_name': 'Constraint Test OS',
            'version': '1.0'
        }
        
        # 创建第一个操作系统
        create_result = self.os_service.create_os(os_data)
        if not create_result['success']:
            logger.error(f"创建第一个操作系统失败: {create_result['message']}")
            return False
        
        os_id1 = create_result['data']['os_id']
        
        # 尝试创建相同的操作系统（应该失败）
        create_result2 = self.os_service.create_os(os_data)
        if create_result2['success']:
            logger.error("创建重复操作系统应该失败")
            self.os_service.delete_os(os_id1)
            return False
        
        # 测试删除不存在的操作系统
        delete_result = self.os_service.delete_os('non_existent_os_id')
        if delete_result['success']:
            logger.error("删除不存在的操作系统应该失败")
            self.os_service.delete_os(os_id1)
            return False
        
        # 清理测试数据
        self.os_service.delete_os(os_id1)
        
        logger.info("业务约束测试完成")
        return True
    
    def test_os_statistics(self):
        """测试操作系统统计功能"""
        logger.info("测试操作系统统计功能")
        
        try:
            # 获取统计信息
            statistics = self.os_service.get_os_statistics()
            
            # 验证统计信息结构
            required_fields = ['total_count', 'os_distribution', 'asset_type_distribution', 'recent_os']
            for field in required_fields:
                if field not in statistics:
                    logger.error(f"统计信息缺少字段: {field}")
                    return False
            
            # 验证数据类型
            if not isinstance(statistics['total_count'], int):
                logger.error("总数统计类型错误")
                return False
            
            if not isinstance(statistics['os_distribution'], list):
                logger.error("操作系统分布类型错误")
                return False
            
            if not isinstance(statistics['asset_type_distribution'], list):
                logger.error("设备类型分布类型错误")
                return False
            
            if not isinstance(statistics['recent_os'], list):
                logger.error("最近操作系统类型错误")
                return False
            
            logger.info(f"统计信息: 总数={statistics['total_count']}, "
                       f"操作系统类型数={len(statistics['os_distribution'])}, "
                       f"设备类型数={len(statistics['asset_type_distribution'])}")
            
            return True
            
        except Exception as e:
            logger.error(f"获取统计信息失败: {str(e)}")
            return False
    
    def test_os_filter_and_search(self):
        """测试操作系统筛选和搜索功能"""
        logger.info("测试操作系统筛选和搜索功能")
        
        try:
            # 获取所有操作系统
            all_os = self.os_service.get_os_list()
            
            if not all_os:
                logger.info("没有操作系统数据，跳过筛选测试")
                return True
            
            # 测试按设备资产筛选
            filters = {'asset_id': self.test_data['asset']['asset_id']}
            filtered_os = self.os_service.get_os_list(filters)
            
            # 验证筛选结果
            for os_item in filtered_os:
                if os_item['asset_id'] != self.test_data['asset']['asset_id']:
                    logger.error("筛选结果包含不匹配的设备资产")
                    return False
            
            # 测试按操作系统名称筛选
            if all_os:
                first_os = all_os[0]
                os_name_part = first_os['os_name'][:3] if len(first_os['os_name']) > 3 else first_os['os_name']
                
                filters = {'os_name': os_name_part}
                filtered_os = self.os_service.get_os_list(filters)
                
                # 验证筛选结果
                for os_item in filtered_os:
                    if os_name_part.lower() not in os_item['os_name'].lower():
                        logger.error("操作系统名称筛选结果不正确")
                        return False
            
            # 测试按版本号筛选
            if all_os:
                first_os = all_os[0]
                if first_os['version']:
                    version_part = first_os['version'][:2] if len(first_os['version']) > 2 else first_os['version']
                    
                    filters = {'version': version_part}
                    filtered_os = self.os_service.get_os_list(filters)
                    
                    # 验证筛选结果
                    for os_item in filtered_os:
                        if version_part not in os_item['version']:
                            logger.error("版本号筛选结果不正确")
                            return False
            
            logger.info("筛选和搜索功能测试完成")
            return True
            
        except Exception as e:
            logger.error(f"筛选和搜索测试失败: {str(e)}")
            return False
    
    def test_os_data_integrity(self):
        """测试操作系统数据完整性"""
        logger.info("测试操作系统数据完整性")
        
        try:
            # 准备完整的测试数据
            os_data = {
                'asset_id': self.test_data['asset']['asset_id'],
                'os_name': 'Integrity Test OS',
                'version': '1.0.0',
                'install_dir': '/opt/integrity_test',
                'install_date': '2023-01-01'
            }
            
            # 创建操作系统
            create_result = self.os_service.create_os(os_data)
            if not create_result['success']:
                logger.error(f"创建操作系统失败: {create_result['message']}")
                return False
            
            os_id = create_result['data']['os_id']
            
            # 获取详细信息
            details = self.os_service.get_os_details(os_id)
            if not details:
                logger.error("获取操作系统详细信息失败")
                self.os_service.delete_os(os_id)
                return False
            
            # 验证关键字段
            required_fields = [
                'os_id', 'asset_id', 'asset_name', 'asset_type',
                'os_name', 'version', 'create_time', 'update_time',
                'business_systems_count', 'middlewares_count', 'ip_count'
            ]
            
            for field in required_fields:
                if field not in details:
                    logger.error(f"详细信息缺少字段: {field}")
                    self.os_service.delete_os(os_id)
                    return False
            
            # 验证数据类型
            if not isinstance(details['business_systems_count'], int):
                logger.error("业务系统数量类型错误")
                self.os_service.delete_os(os_id)
                return False
            
            if not isinstance(details['middlewares_count'], int):
                logger.error("中间件数量类型错误")
                self.os_service.delete_os(os_id)
                return False
            
            if not isinstance(details['ip_count'], int):
                logger.error("IP数量类型错误")
                self.os_service.delete_os(os_id)
                return False
            
            # 验证关联数据结构
            if 'business_systems' in details and not isinstance(details['business_systems'], list):
                logger.error("业务系统数据结构错误")
                self.os_service.delete_os(os_id)
                return False
            
            if 'middlewares' in details and not isinstance(details['middlewares'], list):
                logger.error("中间件数据结构错误")
                self.os_service.delete_os(os_id)
                return False
            
            if 'ips' in details and not isinstance(details['ips'], list):
                logger.error("IP数据结构错误")
                self.os_service.delete_os(os_id)
                return False
            
            # 清理测试数据
            self.os_service.delete_os(os_id)
            
            logger.info("数据完整性测试完成")
            return True
            
        except Exception as e:
            logger.error(f"数据完整性测试失败: {str(e)}")
            return False
    
    def run_all_tests(self):
        """运行所有回归测试"""
        logger.info("=" * 60)
        logger.info("开始操作系统模块回归测试")
        logger.info("=" * 60)
        
        start_time = time.time()
        
        # 设置测试数据
        if not self.setup_test_data():
            logger.error("设置测试数据失败，终止测试")
            return False
        
        # 运行测试
        tests = [
            ("操作系统工具类验证功能", self.test_os_utils_validation),
            ("操作系统缓存操作", self.test_os_cache_operations),
            ("操作系统CRUD操作", self.test_os_crud_operations),
            ("操作系统业务约束", self.test_os_business_constraints),
            ("操作系统统计功能", self.test_os_statistics),
            ("操作系统筛选和搜索功能", self.test_os_filter_and_search),
            ("操作系统数据完整性", self.test_os_data_integrity)
        ]
        
        passed = 0
        failed = 0
        
        for test_name, test_func in tests:
            if self.run_test(test_name, test_func):
                passed += 1
            else:
                failed += 1
        
        # 输出测试结果
        duration = time.time() - start_time
        
        logger.info("=" * 60)
        logger.info("回归测试结果汇总")
        logger.info("=" * 60)
        logger.info(f"总测试数: {len(tests)}")
        logger.info(f"通过: {passed}")
        logger.info(f"失败: {failed}")
        logger.info(f"总耗时: {duration:.2f}秒")
        
        # 详细结果
        logger.info("\n详细测试结果:")
        for result in self.test_results:
            status_icon = "✅" if result['status'] == 'PASS' else "❌"
            logger.info(f"{status_icon} {result['name']} - {result['status']} ({result['duration']:.2f}s)")
            if result['status'] != 'PASS':
                logger.info(f"   错误信息: {result['message']}")
        
        # 保存测试报告
        self.save_test_report()
        
        success_rate = (passed / len(tests)) * 100
        logger.info(f"\n测试通过率: {success_rate:.1f}%")
        
        if failed == 0:
            logger.info("🎉 所有回归测试通过！")
            return True
        else:
            logger.error(f"❌ {failed} 个测试失败")
            return False
    
    def save_test_report(self):
        """保存测试报告"""
        try:
            report_path = 'tests/os_regression_test_report.txt'
            
            with open(report_path, 'w', encoding='utf-8') as f:
                f.write("操作系统模块回归测试报告\n")
                f.write("=" * 50 + "\n")
                f.write(f"测试时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
                f.write(f"总测试数: {len(self.test_results)}\n")
                
                passed = sum(1 for r in self.test_results if r['status'] == 'PASS')
                failed = sum(1 for r in self.test_results if r['status'] == 'FAIL')
                errors = sum(1 for r in self.test_results if r['status'] == 'ERROR')
                
                f.write(f"通过: {passed}\n")
                f.write(f"失败: {failed}\n")
                f.write(f"错误: {errors}\n\n")
                
                f.write("详细结果:\n")
                f.write("-" * 50 + "\n")
                
                for result in self.test_results:
                    f.write(f"{result['name']}: {result['status']}\n")
                    f.write(f"  耗时: {result['duration']:.2f}秒\n")
                    if result['status'] != 'PASS':
                        f.write(f"  错误信息: {result['message']}\n")
                    f.write("\n")
            
            logger.info(f"测试报告已保存到: {report_path}")
            
        except Exception as e:
            logger.error(f"保存测试报告失败: {str(e)}")

def main():
    """主函数"""
    test = OsRegressionTest()
    success = test.run_all_tests()
    
    # 返回适当的退出码
    sys.exit(0 if success else 1)

if __name__ == '__main__':
    main()